#include "FeeTest.h"

#include "Can_Debug.h"


#define FEE_BLOCK_1 1
#define FEE_BLOCK_2 2
#define FEE_BLOCK_3 3
#define FEE_BLOCK_4 4


static CONST (uint8, AUTOMATIC) FeeTest_WriteBuff[32]={0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
                                   0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                                   0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA};
static VAR (uint8, AUTOMATIC)  FeeTest_ReadBuff[32]={0};
/**
@brief      SampleAppFee_memcmp - Compare two SampleApp_WriteBuffers of memory
@details    This function compare the contents of two SampleApp_WriteBuffer of the same length.

@return     E_OK when SampleApp_WriteBuffers contents match, E_NOT_OK when the SampleApp_WriteBuffers are different
@retval     E_OK or E_NOT_OK

@pre None
@post None
*/
static FUNC (Std_ReturnType, SAMPLE_APP_CODE) SampleAppFee_memcmp(P2VAR(uint8, AUTOMATIC, SAMPLE_APP_VAR) src1,
                                                 P2VAR(uint8, AUTOMATIC, SAMPLE_APP_VAR) src2,
                                                 VAR(uint16, AUTOMATIC) len)
{
    /* local variables here */
    Std_ReturnType stdRet = E_OK;
    uint16 i;

    i = 0U;
    do
    {
        if (0x0U != (src1[i]^src2[i]))
        {
            stdRet = E_NOT_OK;
        }
        i++;
    }
    while ((stdRet==E_OK) && (i<len));

    return stdRet;
}
FeeDriverState FeeState;      /* State machine state */
VAR( uint16, AUTOMATIC ) FeeBankIdx;
TASK( OsTask_FeeTest )
{
    volatile StatusType status;                 /* variable to check system status */
    Std_ReturnType stdRet = E_NOT_OK;
    MemIf_StatusType memif_status;

    memif_status = Fee_GetStatus();

    /* state-machine logic */
    switch(FeeState)
    {
        case FEE_ERASE_STATE:
        {
            if (MEMIF_IDLE == memif_status)
            {
                stdRet = Fee_EraseImmediateBlock(FeeBankIdx);
                if (stdRet != E_OK)
                {
//                    CONSOLE_MESSAGE("FEE Error %d returned by Fee_EraseImmediateBlock()", stdRet);
                    Can_PduInfo_0_0.sdu[0] = 0x01;
                    /*CONSOLE_MESSAGE("FEE state-machine state:%d", FeeState);*/
                    FeeState = FEE_ERROR_STATE;
                }
                else
                {
                    /* change the state */
                    FeeState = FEE_ERASE_BUSY_STATE;
                    Can_PduInfo_0_0.sdu[0] = 0x00;
                    stdRet = E_OK;
                }
            }
            else
            {
                stdRet = E_OK;
            }
        }
        break;
        case FEE_ERASE_BUSY_STATE:
            if (MEMIF_IDLE == memif_status)
            {
                FeeState = FEE_WRITE_STATE;
            }
            stdRet = E_OK;
        break;
        case FEE_WRITE_STATE:
        {
            if (MEMIF_IDLE == memif_status)
            {
                stdRet = Fee_Write(FeeBankIdx, (uint8 *)FeeTest_WriteBuff);
                if (stdRet != E_OK)
                {
//                    CONSOLE_MESSAGE("FEE Error returned by Fee_Write()", stdRet);
                    Can_PduInfo_0_0.sdu[0] = 0x02;
                    /*CONSOLE_MESSAGE("FEE state-machine state:", FeeState);*/
                    FeeState = FEE_ERROR_STATE;
                }
                else
                {
                    /* change the state */
                    FeeState = FEE_WRITE_BUSY_STATE;
                    stdRet = E_OK;
                }
            }
            else
            {
                stdRet = E_OK;
            }
        }
        break;
        case FEE_WRITE_BUSY_STATE:
            if (MEMIF_IDLE == memif_status)
            {
                FeeState = FEE_READ_STATE;
            }
            stdRet = E_OK;
        break;
        case FEE_READ_STATE:
        {
            if (MEMIF_IDLE == memif_status)
            {
                stdRet = Fee_Read(FeeBankIdx, 0, FeeTest_ReadBuff, 32u);
                if (stdRet != E_OK)
                {
//                    CONSOLE_MESSAGE("FEE Error %d returned by Fee_Read()", stdRet);
                    Can_PduInfo_0_0.sdu[0] = 0x03;
                    /*CONSOLE_MESSAGE("FEE state-machine state:", FeeState);*/
                    FeeState = FEE_ERROR_STATE;
                }
                else
                {
                    /* change the state */
                    FeeState = FEE_READ_BUSY_STATE;
                }
            }
            else
            {
                stdRet = E_OK;
            }
        }
        break;
        case FEE_READ_BUSY_STATE:
            if (MEMIF_IDLE == memif_status)
            {
                FeeState = FEE_VALIDATE_STATE;
            }
             stdRet = E_OK;
        break;
        case FEE_VALIDATE_STATE:
        {
            /* compare the read FeeTest_WriteBuffer with the written one */
            stdRet = SampleAppFee_memcmp((uint8 *)FeeTest_WriteBuff, FeeTest_ReadBuff, 32u);
            if (stdRet != E_OK)
            {
                Can_PduInfo_0_0.sdu[0] = 0x04;
//                CONSOLE_MESSAGE("FEE Error %d returned by SampleAppFee_memcmp()", stdRet);
                /*CONSOLE_MESSAGE("FEE state-machine state:%d", FeeState);*/
                FeeState = FEE_READ_ERROR_STATE;
//                CONSOLE_MESSAGE("Fee task READ ERROR!", 0);
            }
            else
            {
                /* change the state */
                FeeState = FEE_FINAL_STATE;
                Can_PduInfo_0_0.sdu[0] = 0xFF;
                if(FeeBankIdx < 4)
                {
                    FeeBankIdx++;
                    FeeState = FEE_ERASE_STATE;
                }
//                CONSOLE_MESSAGE("Fee task ended OK.", 0);
            }
        }
        break;

        case FEE_ERROR_STATE:
        {

        }
        /*break;*/

        default:
        {
            /* if we got here, something went terribly wrong*/
            stdRet = E_NOT_OK;
        }
        break;
    }



    status = TerminateTask();
}



/**
@brief      Fee_JobEndNotif - Notification function called from Fee driver
@details    This notification function is called by Fee driver after job end.

@return     none
@retval     none

@pre None
@post None
*/
/* Job End Notifications */
FUNC (void, SAMPLE_APP_CODE) Fee_JobEndNotif (void)
{
#if (USE_FEE_MODULE==STD_ON) && (USE_FLS_MODULE==STD_ON)
    switch(stSampleAppData.stFeeData.ucState)
    {
        case FEE_ERASE_BUSY_STATE:
        {
            stSampleAppData.stFeeData.ucState = FEE_WRITE_STATE;
            break;
        }
        case FEE_WRITE_BUSY_STATE:
        {
            stSampleAppData.stFeeData.ucState = FEE_READ_STATE;
            break;
        }
        case FEE_READ_BUSY_STATE:
        {
            stSampleAppData.stFeeData.ucState = FEE_VALIDATE_STATE;
            break;
        }
        default:
        {
            stSampleAppData.stFeeData.ucState = FEE_ERROR_STATE;
        }
    }
#endif
}

/**
@brief      Fee_JobErrorNotif - Notification function called from Fee driver
@details    This notification function is called by Fee driver when an error occurs in the job.

@return     none
@retval     none

@pre None
@post None
*/
/*================================================================================================*/
/* Job Error Notifications */
FUNC (void, SAMPLE_APP_CODE) Fee_JobErrorNotif (void)
{
#if (USE_FEE_MODULE==STD_ON) && (USE_FLS_MODULE==STD_ON)
    stSampleAppData.stFeeData.ucState = FEE_ERROR_STATE;
    CONSOLE_MESSAGE("FEE: Job Error Notification Handler!", 0);
#endif
}

